from collections import  Iterable
from collections.abc import Iterator

# 切片
L = ['Michael', 'Sarah', 'Tracy', 'Bob', 'Jack']

print(L[0: 3])     # 从索引0开始，直到索引3，不包括索引3
print(L[: 3])      # 同上，第一个索引是0时的省略写法
print(L[-2:])      # 倒数切片，省略末尾
print(L[-2: -1])

L = list(range(100))  # 生成0~99

print(L[: 10: 2])     # 前10个数，每隔2个取1个

print((1,2,3,4,5,6)[: 3])   # tuple切片
print('ABCDEFG'[: 3])       # 字符串切片

# 迭代
d = {'a': 1, 'b': 2, 'c': 3}   # list的三种迭代

for key in d:            # 按key遍历
    print(key)

for value in d.values(): # 按value遍历
    print(value)

for k, v in d.items():   # 按item遍历
    print(k)
    print(v)

print(isinstance([1, 2, 3],Iterable))    # 判断一个对象是否可迭代

for i, value in enumerate(['A', 'B', 'C']):   # 按下标迭代（enumerate）
    print(i, value)

# 列表生成器
print(list(range(1, 11)))
print([x * x for x in range(1, 11)])
print([i + j for i in 'ABC' for j in 'DE'])
print([x * x for x in range(1, 11) if x % 2 == 0])  # 在一个列表生成式中，for后面的if是过滤条件，不能带else
print([x if x % 2 == 0 else -x for x in range(1, 11)])  # 而for前面的if ... else是表达式

# 生成器（边循环边计算结果）
myiter = (x * x for x in range(10))   # 外层()表示生成迭代器，[]表示生成列表
print(next(myiter))       # 没有元素时抛出StopIteration

for n in myiter:          # for循环遍历迭代器时，不用担心StopIteration错误
    print(n)

def fibonacci_sequence(max):  # 函数定义中包含yield关键字，其则是一个generator，
    n, a, b = 0, 0, 1         # 每次调用next()的时候执行，遇到yield语句返回，再次执行时从上次返回的yield语句处继续执行
    while n < max:
        yield b
        a, b = b, a + b
        n = n + 1
    return 'done'

g = fibonacci_sequence(6)
while True:
    try:
        x = next(g)
        print('g: ', x)
    except StopIteration as e:
        print('Generator return value', e.value)
        break

# 迭代器
# 生成器都是Iterator对象，但list、dict、str虽然是Iterable，却不是Iterator
# print(isinstance(iter('abc'), Iterator))
print(isinstance(iter('abc'), Iterator))
print(isinstance([], Iterator))
